<template>
  <div
    class="display-item"
    style="display: inline"
    @click="handleClick"
    v-if="!getHiddenValue"
  >
    <div
      v-if="exclusiveRow"
      :class="[
        props.disabled ? 'exclusive-row' : 'exclusive-row-hover',
        { choose: chooseStatus },
      ]"
    >
      <component
        :is="componentItem"
        v-bind="cmpProps"
        :schema="props.schema"
        :formData="props.formData"
        :IDMap="props.IDMap"
        @changeFormItemData="changeFormItemData"
      />
      <i
        v-if="!props.disabled"
        :class="['icon-close', 'delete', { 'delete-show': chooseStatus }]"
        @click.stop="handleDelete"
      >
        X
      </i>
    </div>
    <el-form-item
      v-else
      v-bind="elFormItemProps"
      :class="[
        props.disabled
          ? 'component-item-wrapper'
          : 'component-item-wrapper-hover',
        { hover: !props.disabled },
        { choose: chooseStatus },
      ]"
      :error="handleError()"
    >
      <component
        :is="componentItem"
        v-bind="cmpProps"
        :schema="props.schema"
        :formData="props.formData"
        :IDMap="props.IDMap"
        :style="
          props.schema?.component?.componentStyle.width
            ? { width: `${props.schema.component.componentStyle.width}px` }
            : {}
        "
        @changeFormItemData="changeFormItemData"
      />
      <i
        v-if="!props.disabled"
        :class="['icon-close', 'delete', { 'delete-show': chooseStatus }]"
        @click.stop="handleDelete"
      >
        X
      </i>
    </el-form-item>
  </div>
</template>

<script setup lang="ts">
import { displayComponents } from "../../base-components";
import {
  ComponentProps,
  DraggableTreeNode,
  FormDataType,
  IDMapType,
} from "../../type";
import { getHidden } from "../../uitls";
import { computed, PropType } from "vue";

const props = defineProps({
  formData: {
    type: Object as PropType<FormDataType>,
    default: () => {
      return {};
    },
  },
  IDMap: {
    type: Object as PropType<IDMapType>,
    default: () => {
      return {};
    },
  },
  schema: {
    type: Object as PropType<DraggableTreeNode | null>,
    default: () => {
      return {};
    },
  },
  currentItem: {
    type: Object as PropType<DraggableTreeNode | null>,
    default: null,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
});
const exclusiveRow = computed(() => {
  return props.schema?.row;
});
const elFormItemProps = computed(() => {
  if (!props.schema) return {};
  // return props.schema.component?.elFormItemProps;
  const { label, component } = props.schema;
  return {
    ...component?.elFormItemProps,
    label,
  };
});
const cmpProps = computed(() => {
  const cmp: ComponentProps = props.schema?.component
    ? props.schema.component.componentProps
    : {};
  return cmp;
});
const componentItem = computed(() => {
  if (!props.schema) return;
  return displayComponents[props.schema.componentType];
});
// 高亮判断
const chooseStatus = computed(() => {
  if (!props.currentItem) {
    return false;
  } else if (props.schema?.id === props.currentItem.id) {
    return true;
  }
  return false;
});
// 获取当前shcema required
const required = computed(() => {
  if (!props.schema) return;
  const { component } = props.schema;
  return component ? component.elFormItemProps?.required : false;
});
// 获取必选提示
const errorMessage = computed(() => {
  if (!props.schema) return;
  const { component } = props.schema;
  return component ? String(component) : "请输入";
});
const handleError = () => {
  if (!props.schema) return "没有schema";
  const value =
    props.formData[props.IDMap[props.schema.id]] === null
      ? ""
      : String(props.formData[props.IDMap[props.schema.id]]);
  if (required) {
    return String(value) ? "" : errorMessage.value;
  }
  return "找不到当前组件";
};
// 显隐规则处理
const getHiddenValue = computed(() => {
  if (!props.schema?.component) {
    return false;
  }
  return getHidden(
    props.schema.component.hiddenRules,
    props.formData,
    props.IDMap
  );
});
const emit = defineEmits([
  "changeFormItemData",
  "setCurrentItem",
  "deleteCurrentItem",
]);
function changeFormItemData(e: any) {
  emit("changeFormItemData", e);
}
function handleClick() {
  emit("setCurrentItem", props.schema);
}
function handleDelete() {
  emit("deleteCurrentItem", props.schema);
}
</script>

<style lang="scss" scoped>
@mixin color($color) {
  @if $color == "primary" {
    color: #409eff;
  } @else if $color == "danger" {
    color: #f56c6c;
  } @else {
    color: #606266;
  }
}
.icon-close {
  --r: 20px;
  width: var(--r);
  height: var(--r);
}
.exclusive-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 20px;
  margin-bottom: 10px;
  .delete {
    visibility: hidden;
    margin-left: 10px;
    @include color("danger");
    cursor: pointer;
  }
  .delete-show {
    visibility: visible;
  }
}
.exclusive-row-hover {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 20px;
  margin-bottom: 10px;
  &:hover {
    background-color: rgba(9, 96, 189, 0.2);
    cursor: move;
    .delete {
      visibility: visible;
    }
  }
  .delete {
    visibility: hidden;
    margin-left: 10px;
    @include color("danger");
    cursor: pointer;
  }
  .delete-show {
    visibility: visible;
  }
}
.component-item-wrapper {
  padding: 10px 20px;
  .delete {
    visibility: hidden;
    margin-left: 10px;
    @include color("danger");
    cursor: pointer;
  }
  .delete-show {
    visibility: visible;
  }
}
.component-item-wrapper-hover {
  padding: 10px 20px;
  &:hover {
    background-color: rgba(9, 96, 189, 0.2);
    cursor: move;
    .delete {
      visibility: visible;
    }
  }
  .delete {
    visibility: hidden;
    margin-left: 10px;
    @include color("danger");
    cursor: pointer;
  }
  .delete-show {
    visibility: visible;
  }
}
.choose {
  border: 2px solid #4895fd;
  background-color: rgba(9, 96, 189, 0.2);
}

.display-item {
  :deep(.el-form-item__content) {
    display: flex;
  }
}
</style>
